package com.movie2.controller;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.*;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.movie2.annotation.DisableBaseResponse;
import com.movie2.config.AlipayConfig;
import com.movie2.model.vo.PayReturnVo;
import com.movie2.model.vo.PayVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

@CrossOrigin
@Controller
@Slf4j
public class PayController {
    @Autowired
    private AlipayConfig alipayConfig;

    @GetMapping("favicon.ico")
    @ResponseBody
    private void returnNoFavicon() {
    }

    @RequestMapping("/other/success")
    @ResponseBody
    @DisableBaseResponse
    public String other(@ModelAttribute PayReturnVo vo) {
        //没有办法处理支付失败的问题？？？，如果余额不足，是不会有输入支付密码的页面的，会提供 其他的支付方式。
        System.out.println("支付完成");
        System.out.println(vo);
        // 修改我们自己的数据库（订单的状态）

        //支付成功后返回内容，可以使用request 保存该对象，创建一个vo自动填充
        // 字符集
        // charset=UTF-8
        // 自己的订单号
        // out_trade_no=t909j9o
        // 方法？？？
        // method=alipay.trade.page.pay.return
        // 金额
        // total_amount=200.00
        // 不知道
        // sign=XIKwNPhg9nWz3kdqXZyqmFJxq%2BwJDezNXIgZk%2Bg5hl8jSnCu8uThXoBaQm6ry2Psi3fjJci k8858odqR1nn7wFFJ%2Fbz%2FtK9xV0FMTvrZVWLslQasQN%2B16n8m25iQCYrIXQAq2lNARnooMo9b1 4rrFts7zM%2FFrQ9ah9kO1QKAGTG2MjndAz1VuVzznfhV2SJoQBrySHYf7AoLBbIexJ5JZOHLH5wI69V DoUglo8DpEL8z%2FGz6hlgmLFAHOMxNn9ysUB5LTyX4QMTPUFVNIBCpOoeUxyPKlEWi40BC0ai5SppdI ki5RewqpNc8CIzGfx4Gsi%2BPYlsXv674Um8d4xdYQA%3D%3D
        // 生成的订单号
        // trade_no=2022052622001443940503814010
        // appId
        // auth_app_id=2021000118657064
        // 版本
        // version=1.0
        // appId
        // app_id=2021000118657064
        // 秘钥类型
        // sign_type=RSA2
        // 商户PID
        // seller_id=2088621957175454
        // 交易时间，日期要转一下， + 代表空格， %3A 代表冒号
        // timestamp=2022-05-26+19%3A58%3A57
        // 这里可以修改数据库，或保存其他内容

        return "success";
    }

    public AlipayClient getAlipayClient() {
        DefaultAlipayClient defaultAlipayClient = new DefaultAlipayClient(
                alipayConfig.URL,
                alipayConfig.APPID,
                alipayConfig.RSA_PRIVATE_KEY,
                alipayConfig.FORMAT,
                alipayConfig.CHARSET,
                alipayConfig.ALIPAY_PUBLIC_KEY,
                alipayConfig.SIGNTYPE);
        return defaultAlipayClient;
    }

    // 获得客户端
    // 生成的公钥私钥
    @PostMapping("/pay/pay")
    @ResponseBody
    // public void pay(@RequestBody PayVo vo,HttpServletResponse resp) throws IOException {
    public void pay(String out_trade_no, String subject, String total_amount, HttpServletResponse resp) throws IOException {
        //System.out.println(alipayConfig);
        // System.out.println(vo);
        System.out.println(out_trade_no);
        System.out.println(subject);
        System.out.println(total_amount);
        // 创建客户端
        AlipayClient client = this.getAlipayClient();
        // AlipayClient client = new DefaultAlipayClient(AlipayConfig.URL,
        // AlipayConfig.APPID,AlipayConfig.RSA_PRIVATE_KEY,AlipayConfig.FORMAT,
        // AlipayConfig.CHARSET,AlipayConfig.ALIPAY_PUBLIC_KEY,AlipayConfig.SIGNTYPE);
        // 创建页面请求
        AlipayTradePagePayRequest alipay_request = new AlipayTradePagePayRequest();
        // 设置异步通知地址
        // alipay_request.setNotifyUrl(AlipayConfig.notify_url);
        alipay_request.setNotifyUrl(alipayConfig.notify_url);
        // 设置支付成功返回地址（注意）
        // alipay_request.setReturnUrl(AlipayConfig.return_url);
        alipay_request.setReturnUrl(alipayConfig.return_url);
        //要提交的数据（必须有，key 是不能修改的）
        JSONObject bizContent = new JSONObject();
        // bizContent.put("out_trade_no", vo.getOut_trade_no());
        bizContent.put("out_trade_no", out_trade_no);
        // bizContent.put("total_amount", vo.getTotal_amount());
        bizContent.put("total_amount", total_amount);
        // bizContent.put("subject", vo.getSubject());
        bizContent.put("subject", subject);
        bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");//订单号不能自己 填，自己填就报错
        alipay_request.setBizContent(bizContent.toString());
        // 处理响应
        AlipayTradePagePayResponse response = null;
        try {
            response = client.pageExecute(alipay_request);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        resp.setContentType("text/html;charset=utf-8");
        resp.setCharacterEncoding("utf-8");
        PrintWriter out = resp.getWriter();
        // 单体项目（显示网页ok）
        // 前后端项目（简单提交，http提交，不要用ajax）
        Map<String, Object> map = new HashMap<>();
        if (response.isSuccess()) {
            // 这里成功，只能表示获得了相应的支付登录页面，并不是支付成功
            // System.out.println("response.getTradeNo():"+response.getTradeNo());
            // System.out.println("response.getSellerId():"+response.getSellerId());
            // System.out.println("response.getCode():"+response.getCode());
            // System.out.println("response.getOutTradeNo():"+response.getOutTradeNo());
            // System.out.println("response.getTradeNo():"+response.getTradeNo());
            // System.out.println("response.getMsg():"+response.getMsg());
            // System.out.println("response.getBody():"+response.getBody());// 这里 是一个html代码，就是返回的支付页面，其他数据都是null
            //
            // System.out.println("response.getParams():"+response.getParams());
            // System.out.println("response.getSubCode():"+response.getSubCode());
            // System.out.println("response.getTotalAmount():"+response.getTotalAmount());
            // System.out.println("response.getMerchantOrderNo():"+response.getMerchantOrderNo( ));
            // System.out.println("response.getSubMsg():"+response.getSubMsg());
            System.out.println("调用成功");
            System.out.println(response.getBody());
            out.write(response.getBody());
            out.close();
            // map.put("result",);
            // return response.getBody();
        } else {
            System.out.println("调用失败");
            // map.put("result",null);
            // return null;
        }
        // return map;
    }

    /**
     * 退款
     *
     * @param outTradeNo   订单编号
     * @param refundReason 退款原因
     * @param refundAmount 退款原因
     * @param outRequestNo 标识一次退款请求，同一笔交易多次退款需要保证唯一，如需部分退款，则此参数必传
     * @return java.lang.String
     * @url TODO
     * @json_param 传入参数
     * @return_param 返回参数
     */
    @ResponseBody
    @RequestMapping("/pay/refund")
    @DisableBaseResponse
    public String refund(@RequestParam("WIDout_trade_no") String outTradeNo, @RequestParam("WIDrefund_reason") String refundReason,
                         @RequestParam("WIDrefund_amount") Integer refundAmount, @RequestParam("WIDout_request_no") String outRequestNo) throws AlipayApiException {
        //https://blog.csdn.net/weixin_45853881/article/details/122597951
        Integer pay = Integer.valueOf(refundAmount);
        AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", outTradeNo);
        bizContent.put("refund_amount", refundAmount);
        bizContent.put("refund_reason", refundReason);
        bizContent.put("out_request_no", outRequestNo);
        alipayRequest.setBizContent(bizContent.toString());
        AlipayClient client = new DefaultAlipayClient(AlipayConfig.URL,
                AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT,
                AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.SIGNTYPE);
        String result = client.execute(alipayRequest).getBody();

        //日志
        AlipayConfig.logResult(alipayRequest.getBizContent());
        return result;


    }

    /*-------------------- 退款查询 --------------------*/
    @RequestMapping("/pay/refundquery")
    @DisableBaseResponse
    @ResponseBody
    public String refundquery(@RequestParam("WIDout_trade_no") String outTradeNo,
                              @RequestParam("WIDout_request_no") String outRequestNo) throws AlipayApiException {
        AlipayClient client = new DefaultAlipayClient(AlipayConfig.URL,
                AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT,
                AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.SIGNTYPE);
        AlipayTradeFastpayRefundQueryRequest alipayRequest = new AlipayTradeFastpayRefundQueryRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", outTradeNo);
        bizContent.put("out_request_no", outRequestNo);
        alipayRequest.setBizContent(bizContent.toString());
        //格式转换
        String result = client.execute(alipayRequest).getBody();

        //订单号与请求号：
        return result;
    }

    /*-------------------- 单个查询 --------------------*/
    @RequestMapping("/pay/query")
    @DisableBaseResponse
    @ResponseBody
    public String query(@RequestParam("WIDout_trade_no") String outTradeNo) throws AlipayApiException {
        AlipayClient client = new DefaultAlipayClient(AlipayConfig.URL,
                AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT,
                AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.SIGNTYPE);
        AlipayTradeQueryRequest alipayRequest = new AlipayTradeQueryRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", outTradeNo);
        bizContent.put("trade_no", "");
        alipayRequest.setBizContent(bizContent.toString());
        //转换格式
        String result = client.execute(alipayRequest).getBody();

        return result;
    }

    /*-------------------- 关闭交易 --------------------*/
    @RequestMapping("/pay/close")
    @DisableBaseResponse
    @ResponseBody
    public String close(@RequestParam("WIDout_trade_no") String outTradeNo) throws AlipayApiException {
        AlipayClient client = new DefaultAlipayClient(AlipayConfig.URL,
                AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT,
                AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.SIGNTYPE);
        AlipayTradeCloseRequest alipayRequest = new AlipayTradeCloseRequest();
        JSONObject bizContent = new JSONObject();

        bizContent.put("out_trade_no", outTradeNo);
        bizContent.put("trade_no", "");
        alipayRequest.setBizContent(bizContent.toString());
        String result = client.execute(alipayRequest).getBody();

        return result;
    }

    /*-------------------- 下单地址查询 --------------------*/
    @RequestMapping("/pay/bill")
    @DisableBaseResponse
    @ResponseBody
    public String billDownload() throws AlipayApiException {
        AlipayClient client = new DefaultAlipayClient(AlipayConfig.URL,
                AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT,
                AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.SIGNTYPE);
        AlipayDataDataserviceBillDownloadurlQueryRequest alipayRequest = new AlipayDataDataserviceBillDownloadurlQueryRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", "zsp001");
        bizContent.put("bill_type", "trade");
        bizContent.put("bill_date", "2022-05-26");
        alipayRequest.setBizContent(bizContent.toString());
        String result = client.execute(alipayRequest).getBody();//需要转码，有乱码
        return result;
    }
}
